﻿using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Controls;
using System.Collections.Generic;
using System;
using System.Linq;
using System.IO;
using Microsoft.Win32;
using BesAsm.Stormwater.Swmm5Results;
using BesAsm.Stormwater.Swmm5ResultsUi.Applications.Views;
using BesAsm.Stormwater.Swmm5ResultsUi.Properties;

namespace BesAsm.Stormwater.Swmm5ResultsUi.Presentation.Views
{
  [Export(typeof(IShellView))]
  public partial class ShellWindow : Window, IShellView
  {
    List<string> _swmmOutputMru;
    SimulationResults _simResults;

    public ShellWindow()
    {
      InitializeComponent();
      ConfigureMruLists();
    }

    private void ConfigureMruLists()
    {
      RecentFileList.MenuClick += (s, e) => OpenFile(e.Filepath);  
    }

    #region IShellView Members

    public void Open()
    {
      OpenFileDialog ofd = new OpenFileDialog();
      ofd.Filter = "SWMM5 Result Files|*.out;*.otr|All Files|*.*";
      if (ofd.ShowDialog() != true)
        return;

      string file = ofd.FileName;
      OpenFile(file);      
    }

    public void OpenTimeSeriesTool()
    {
      frame1.Navigate(new TimeSeriesTool());
    }

    private void OpenFile(string file)
    {
      try
      {
        OutputFileReader reader = new OutputFileReader(file);
        _simResults = reader.Read();
      }
      catch (Exception ex)
      {
        RecentFileList.RemoveFile(file);
        MessageBox.Show(ex.Message, "Unable to open file", MessageBoxButton.OK, MessageBoxImage.Error);
        return;
      }
      RecentFileList.InsertFile(file);
      this.Title = "SWMM5 Results - " + file;
      frame1.Navigate(new Swmm5ResultsHome(_simResults));     
    }

    #endregion

    private void Window_Closed(object sender, System.EventArgs e)
    {

    }

    private void toolsMenu_Click(object sender, RoutedEventArgs e)
    {
      MenuItem item = e.OriginalSource as MenuItem;
      if (item == null) 
      {         
        return; 
      }

      switch (item.Header.ToString())
      {
        case "Extract Maximum Values":
          ExtractMaximumValues();
          return;
        case "Process Running Averages":
          ProcessRunningAverages();
          return;
        case "Process Running Sums":
          ProcessRunningSums();
          return;
        case "Calculate T0.5":
          double? result = CalculateTQ05();          
          return;
        case "Process Ranked Minimums":
          ProcessRankedMinimums();
          return;
        default:
          MessageBox.Show("Unable to find command " + item.Header.ToString());
          return;
      }

    }

    private double? CalculateTQ05()
    {
      string inputFile;
      string outputFile;

      if (!GetIOFiles(out inputFile, out outputFile, "TQ05"))
        return null;

      double t05 = 0;
      PostProcessor postProcessor = new PostProcessor();

      StreamReader reader = null;
      StreamWriter writer = null;
      try
      {
        reader = new StreamReader(inputFile);
        writer = new StreamWriter(outputFile);
        postProcessor.CalculateTQ05(reader, writer);
      }
      catch (Exception ex)
      {
        MessageBox.Show("Unable to Calculate T0.5: " + ex.Message);
      }
      finally
      {
        if (reader != null)
          reader.Close();
        if (writer != null)
          writer.Close();
      }
      return t05;
    }

    private void ProcessRunningAverages()
    {
      string inputFile;
      string outputFile;

       if (!GetIOFiles(out inputFile, out outputFile, "running_average"))
         return;

      PostProcessor postProcessor = new PostProcessor();

      StreamReader reader = null;
      StreamWriter writer = null;
      try
      {
        reader = new StreamReader(inputFile);
        writer = new StreamWriter(outputFile);

        postProcessor.ProcessRunningAverages(reader, writer);        
      }
      catch (Exception ex)
      {
        MessageBox.Show("Unable to process running averages: " + ex.Message);
      }
      finally
      {
        if (reader != null)
          reader.Close();
        if (writer != null)
          writer.Close();
      }
    }

    private void ProcessRunningSums()
    {
      string inputFile;
      string outputFile;

      if (!GetIOFiles(out inputFile, out outputFile, "running_sum"))
        return;

      PostProcessor postProcessor = new PostProcessor();

      StreamReader reader = null;
      StreamWriter writer = null;
      try
      {
        reader = new StreamReader(inputFile);
        writer = new StreamWriter(outputFile);

        postProcessor.ProcessRunningSums(reader, writer);
      }
      catch (Exception ex)
      {
        MessageBox.Show("Unable to process running sums: " + ex.Message);
      }
      finally
      {
        if (reader != null)
          reader.Close();
        if (writer != null)
          writer.Close();
      }
    }

    private void ProcessRankedMinimums()
    {
      string inputFile;
      string outputFile;

      if (!GetIOFiles(out inputFile, out outputFile, "ranked_minimums"))
        return;

      PostProcessor postProcessor = new PostProcessor();

      StreamReader reader = null;
      StreamWriter writer = null;
      try
      {
        reader = new StreamReader(inputFile);
        writer = new StreamWriter(outputFile);
        
        postProcessor.ProcessRankedMinimums(reader, writer);
      }
      catch (Exception ex)
      {
        MessageBox.Show("Unable to process ranked minimums: " + ex.Message);
      }
      finally
      {
        if (reader != null)
          reader.Close();
        if (writer != null)
          writer.Close();
      }
    }

    private void ExtractMaximumValues()
    {
      string inputFile;
      string outputFile;

      if (!GetIOFiles(out inputFile, out outputFile, "maximums"))
        return;

      PostProcessor postProcessor = new PostProcessor();

      postProcessor.ExtractMaximumValues(inputFile, outputFile);
      
    }

    private bool GetIOFiles(out string inputFile, out string outputFile, string defaultSuffix)
    {
      inputFile = string.Empty;
      outputFile = string.Empty;

      OpenFileDialog ofd = new OpenFileDialog();
      ofd.Filter = "CSV File|*.csv|All Files|*.*";
      ofd.Title = "Select a results CSV to post-process";
      if (ofd.ShowDialog() != true)
        return false;

      inputFile = ofd.FileName;

      SaveFileDialog sfd = new SaveFileDialog();
      sfd.Filter = "CSV File|*.csv|All Files|*.*";
      sfd.FileName = System.IO.Path.GetFileNameWithoutExtension(inputFile) + "_"+defaultSuffix + ".csv";
      sfd.Title = "Choose a location to save the post-processed file";
      if (sfd.ShowDialog() != true)
        return false;
      
      outputFile = sfd.FileName;

      return true;
    }
  }
}
